#include "FreeRTOS.h"
#include "common_api.h"
#include "audio_task.h"
#include "bsp_custom.h"
#include "luat_rtos.h"
#include "luat_audio_play_ec618.h"
#include "luat_i2s_ec618.h"
#include "ivTTSSDKID_all.h"
#include "ivTTS.h"
#include "luat_gpio.h"
#include "luat_debug.h"
#include "minimp3.h"
#include "mp3_decode_port.h"
#include "luat_wdt.h"
#include "luat_kv.h"

//AIR780E+TM8211开发板配置
#define CODEC_PWR_PIN HAL_GPIO_12
#define CODEC_PWR_PIN_ALT_FUN	4
#define PA_PWR_PIN HAL_GPIO_25
#define PA_PWR_PIN_ALT_FUN	0
#define CHARGE_EN_PIN	HAL_GPIO_2
#define CHARGE_EN_PIN_ALT_FUN	0

#define AUDIO_QUEUE_SIZE 150

#define MP3_FRAME_SIZE  1152
#define PCM_FRAME_SIZE  (MP3_FRAME_SIZE * 4)

extern const unsigned char audiopoweron[];
extern luat_rtos_task_handle mqtt_publish_task_handle;
static luat_rtos_semaphore_t audio_semaphore_handle;
static luat_rtos_task_handle audio_task_handle;

luat_rtos_queue_t audio_queue_handle;
bool audio_playing;
static uint8_t audio_sleep_handler = 0xff;
static HANDLE g_s_delay_timer;

auStreamFormat_t audio_stream_format;
int sample_rate;
int audio_volume;
int audio_start_count = 5;

mp3dec_t vc;

void audio_data_cb(uint8_t *data, uint32_t len, uint8_t bits, uint8_t channels)
{
    int value = 15;
    int ret = luat_kv_get("volume", &value, sizeof(int));
    if(ret > 0)
    {
        // LUAT_DEBUG_PRINT("cloud_speaker_audio_task get volume success %d", value);       //这里的打印打开会出来很多，影响日志查看，有需要可自行打开
        HAL_I2sSrcAdjustVolumn(data, len, value);
    }
    else
    {
        // LUAT_DEBUG_PRINT("cloud_speaker_audio_task get volume fail %d", value);          //这里的打印打开会出来很多，影响日志查看，有需要可自行打开
        HAL_I2sSrcAdjustVolumn(data, len, 15);
    }
    LUAT_DEBUG_PRINT("cloud_speaker_audio_task %x,%d,%d,%d,%d", data, len, bits, channels);
}
void app_pa_on(uint32_t arg)
{
    luat_gpio_set(PA_PWR_PIN, 1);    //如果是780E+音频扩展小板,可以注释掉此行代码，因为PA长开
}
void audio_event_cb(uint32_t event, void *param)
{
    // LUAT_DEBUG_PRINT("cloud_speaker_audio_task event_cb %d", event);
    switch (event)
    {
    // case MULTIMEDIA_CB_AUDIO_DECODE_START:
    //     luat_gpio_set(CODEC_PWR_PIN, 1);
	// 	luat_audio_play_write_blank_raw(0, 6, 1);
    //     break;
    // case MULTIMEDIA_CB_AUDIO_OUTPUT_START:
    //     luat_rtos_timer_start(g_s_delay_timer, 200, 0, app_pa_on, NULL);     //如果是780E+音频扩展小板,可以注释掉此行代码，因为PA长开
    //     break;
    // case MULTIMEDIA_CB_TTS_INIT:
    //     break;
    // case LUAT_MULTIMEDIA_CB_TTS_DONE:
	// 	if (!luat_audio_play_get_last_error(0))
	// 	{
	// 		luat_audio_play_write_blank_raw(0, 1, 0);
	// 	}
	// 	break;
    case MULTIMEDIA_CB_AUDIO_NEED_DATA:
        add_pcm_data();
        break;
    case MULTIMEDIA_CB_AUDIO_DONE:
        luat_audio_play_stop_raw(0);
        luat_rtos_timer_stop(g_s_delay_timer);
        LUAT_DEBUG_PRINT("audio play done, result=%d!", luat_audio_play_get_last_error(0));
        luat_gpio_set(PA_PWR_PIN, 0);                                          //如果是780E+音频扩展小板,可以注释掉此行代码，因为PA长开
        luat_gpio_set(CODEC_PWR_PIN, 0);

        audio_playing = false;
        luat_rtos_message_send(mqtt_publish_task_handle, 1, &audio_playing);
        break;
    }
}

void add_pcm_data()
{
    audioQueueData audioQueueRecv = {0};
    if (luat_rtos_queue_recv(audio_queue_handle, &audioQueueRecv, NULL, 100) == 0)
    {
        luat_wdt_feed();
        int16_t pcm_frame[1152 * 2];
        uint8_t *data;
        int data_len = 0;

        int offset = 0;
        while (offset < audioQueueRecv.len)
        {
            mp3dec_frame_info_t info;
            int result = mp3dec_decode_frame(&vc, audioQueueRecv.data + offset, audioQueueRecv.len - offset, pcm_frame, &info);
            offset += info.frame_bytes;

            if (data_len == 0)
            {
                data = luat_heap_malloc(result * 2);
                memcpy(data, pcm_frame, result * 2);
            }
            else
            {
                uint8_t *tmp = luat_heap_malloc(data_len + result * 2);
                memcpy(tmp, data, data_len);
                memcpy(tmp + data_len, pcm_frame, result * 2);
                free(data);

                data = tmp;
                tmp = NULL;
            }

            data_len += result * 2;
        }

        HAL_I2sSrcAdjustVolumn(data, data_len, audio_volume);
        luat_audio_play_write_raw(0, data, data_len);

        free(data);
        free(audioQueueRecv.data);
    }
}

void audio_task(void *param)
{
    // luat_kv_get("streamFormat", &audio_stream_format, sizeof(int));
    // luat_kv_get("sampleRate", &sample_rate, sizeof(int));
    // luat_kv_get("volume", &audio_volume, sizeof(int));
    // LUAT_DEBUG_PRINT("streamFormat = %d sampleRate = %d volume = %d", audio_stream_format, sample_rate, audio_volume);
    while (1)
    {
        if (!audio_playing)
        {
            uint32_t cnt;
            luat_rtos_queue_get_cnt(audio_queue_handle, &cnt);
            if (cnt < audio_start_count)
            {
                luat_rtos_task_sleep(10);
                continue;
            }
            int32_t ret = luat_audio_play_start_raw(0, AUSTREAM_FORMAT_PCM, 1, sample_rate, 16, 1);
            luat_gpio_set(CODEC_PWR_PIN, 1);
            luat_audio_play_write_blank_raw(0, 10, 1);
            luat_rtos_timer_start(g_s_delay_timer, 100, 0, app_pa_on, NULL);
            audio_playing = true;
            luat_rtos_message_send(mqtt_publish_task_handle, 1, &audio_playing);
            LUAT_DEBUG_PRINT("开始播放 format=%d rate=%d volume=%d", audio_stream_format, sample_rate, audio_volume);

            add_pcm_data();
            add_pcm_data();
        }
        else
        {
            luat_rtos_task_sleep(100);
        }
    }
    luat_rtos_task_delete(audio_task_handle);
}

void audio_config(auStreamFormat_t format, int rate, int volume, int count)
{
    if (format != NULL && rate != NULL && count != NULL)
    {
        audio_stream_format = format;
        sample_rate = rate;
        audio_start_count = count;
    }
    audio_volume = volume;
}

void audio_task_init(void)
{
    mp3_decoder_init(&vc);
    luat_rtos_timer_create(&g_s_delay_timer);

    luat_gpio_cfg_t gpio_cfg;
	luat_gpio_set_default_cfg(&gpio_cfg);

	gpio_cfg.pull = Luat_GPIO_PULLDOWN;

     //如果是780E+音频扩展小板,可以注释掉下面两行代码，因为PA长开
	gpio_cfg.pin = PA_PWR_PIN;
	luat_gpio_open(&gpio_cfg);

	gpio_cfg.pin = CODEC_PWR_PIN;
	luat_gpio_open(&gpio_cfg);
	gpio_cfg.alt_fun = CODEC_PWR_PIN_ALT_FUN;
	luat_gpio_open(&gpio_cfg);

    luat_audio_play_global_init(audio_event_cb, audio_data_cb, NULL, NULL, NULL);
    luat_i2s_base_setup(0, I2S_MODE_LSB, I2S_FRAME_SIZE_16_16);   //如果是780E+音频扩展小板，打开这行注释代码，这个配置对应ES7148/ES7149
    // luat_i2s_base_setup(0, I2S_MODE_MSB, I2S_FRAME_SIZE_16_16);      //此处配置对应TM8211
	//luat_audio_play_set_bus_type(LUAT_AUDIO_BUS_SOFT_DAC);        //通过DAC引脚播放
    // luat_rtos_semaphore_create(&audio_semaphore_handle, 1);
    audio_stream_format = AUSTREAM_FORMAT_MP3;

    luat_rtos_queue_create(&audio_queue_handle, AUDIO_QUEUE_SIZE, sizeof(audioQueueData));
    int result = luat_rtos_task_create(&audio_task_handle, 8 * 1024, 20, "audio task", audio_task, NULL, NULL);
    LUAT_DEBUG_PRINT("cloud_speaker_audio_task create task result %d", result);
}
